package com.market.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.bean.BeanUtil;
import com.market.model.vo.ProductInfoPageVo;
import com.market.constants.ResultCode;
import com.market.entity.ProductInfo;
import com.market.entity.ProductOrder;
import com.market.entity.ProductVoucher;
import com.market.exception.ServiceException;
import com.market.model.R;
import com.market.model.dto.ProductInfoDto;
import com.market.model.dto.ProductInfoPageDto;
import com.market.model.vo.ProductInfoDetailVo;
import com.market.model.vo.ProductInfoTrendVo;
import com.market.service.ProductInfoService;
import com.market.service.ProductOrderService;
import com.market.service.ProductVoucherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 商品信息控制器
 * 处理商品相关的所有HTTP请求，包括商品发布、查询、收藏、统计等功能
 * 所有接口需要用户登录才能访问
 * @author zhangyihua
 * @version 1.0
 * @date 2024/3/1 21:02
 */
@RestController
@RequestMapping("/product/info")
//@SaCheckLogin
public class ProductInfoController {
  @Autowired
  private ProductInfoService productInfoService;
  @Autowired
  private ProductOrderService productOrderService;
  @Autowired
  private ProductVoucherService productVoucherService;
  
  /**
   * 创建商品信息
   * 用于发布新的商品
   * @param dto 包含商品信息的数据传输对象
   * @return 操作结果
   */
  @PostMapping
  public R createProductInfo(@RequestBody ProductInfoDto dto){
    return productInfoService.createProductInfo(dto);
  }
  
  /**
   * 分页获取商品列表
   * 支持按条件筛选和排序
   * @param pageDto 分页查询参数对象
   * @return 返回商品列表
   */
  @GetMapping("/page")
  public R<List<ProductInfoPageVo>> getProductList(ProductInfoPageDto pageDto){
    List<ProductInfoPageVo> result =  productInfoService.getProductList(pageDto);
    return R.ok(result);
  }
  
  /**
   * 获取商品详情
   * 包括商品基本信息和优惠券信息
   * @param productId 商品ID
   * @return 返回商品详细信息
   */
  @GetMapping("/detail")
  public R<ProductInfoDetailVo> getProductInfo(String productId){
   ProductInfoDetailVo productInfoDetailVo =  productInfoService.getProductInfo(productId);
    ProductVoucher one = productVoucherService.lambdaQuery().eq(ProductVoucher::getProductId, productInfoDetailVo.getId()).one();
    productInfoDetailVo.setProductVoucher(one);
    return R.ok(productInfoDetailVo);
  }
  @SaIgnore
  @PostMapping("/detail")
  public R<ProductInfoDetailVo> _getProductInfo(@RequestParam("productId") String productId){
    ProductInfoDetailVo productInfoDetailVo =  productInfoService.getProductInfo(productId);
    ProductVoucher one = productVoucherService.lambdaQuery().eq(ProductVoucher::getProductId, productInfoDetailVo.getId()).one();
    productInfoDetailVo.setProductVoucher(one);
    return R.ok(productInfoDetailVo);
  }
  
  /**
   * 删除商品信息
   * @param id 商品ID
   * @return 操作结果
   */
  @DeleteMapping("/{id}")
  public R delProductInfo(@PathVariable("id") String id){
    boolean result = productInfoService.removeById(id);
    if(!result) throw new ServiceException(ResultCode.DeleteError);
    return R.ok();
  }
  
  /**
   * 禁用商品
   * 将商品状态设置为禁用(10)
   * @param id 商品ID
   * @return 操作结果
   */
  @PutMapping("/disable/{id}")
  public R disableProductInfo(@PathVariable("id") String id) {
    ProductInfo productInfo = productInfoService.getById(id);
    if (BeanUtil.isEmpty(productInfo)) throw new ServiceException(ResultCode.NotFindError);
    productInfo.setStatus(10);
    boolean result = productInfoService.updateById(productInfo);
    if (!result) throw new ServiceException(ResultCode.UpdateError);
    return R.ok();
  }
  
  /**
   * 获取当前用户发布的商品列表
   * @return 返回用户发布的所有商品
   */
  @GetMapping("/my")
  public R<List<ProductInfo>> getMyProductInfo() {
    List<ProductInfo> list = productInfoService.getMyProductInfoList();
    return R.ok(list);
  }
  
  /**
   * 获取当前用户收藏的商品列表
   * @return 返回用户收藏的所有商品
   */
  @GetMapping("/my/collect")
  public R<List<ProductInfo>> getMyProductCollectInfo() {
    List<ProductInfo> list = productInfoService.getMyProductCollectInfo();
    return R.ok(list);
  }
  
  /**
   * 获取用户的所有商品相关信息（发布、购买、销售）
   * @return 包含发布、购买、销售信息的商品列表
   */
  @GetMapping("/list/my")
  public R<List<ProductInfoTrendVo>> getMyProductInfoList(){
    // 获取用户发布的商品列表
    List<ProductInfo> myProductList = productInfoService.getMyProductInfoList();
    // 将发布的商品转换为趋势视图对象，并标记类型为"publish"
    List<ProductInfoTrendVo> publish = myProductList.stream().map(item -> {
      ProductInfoTrendVo bean = BeanUtil.toBean(item, ProductInfoTrendVo.class);
      bean.setType("publish");
      return bean;
    }).collect(Collectors.toList());
    
    // 获取用户的购买订单列表
    List<ProductOrder> myBuyOrder = productOrderService.getMyBuyOrder();
    // 将购买的商品转换为趋势视图对象，并标记类型为"buy"
    List<ProductInfoTrendVo> buy = myBuyOrder.stream().map(item -> {
      // 根据订单中的商品ID获取商品信息
      ProductInfo productInfo = productInfoService.getById(item.getProductId());
      ProductInfoTrendVo bean = BeanUtil.toBean(productInfo, ProductInfoTrendVo.class);
      // 使用订单创建时间作为时间戳
      bean.setCreateTime(item.getCreateTime().getTime());
      bean.setType("buy");
      return bean;
    }).collect(Collectors.toList());
    
    // 获取用户的销售订单列表
    List<ProductOrder> mySellOrder = productOrderService.getMySellOrder();
    // 将销售的商品转换为趋势视图对象，并标记类型为"sell"
    List<ProductInfoTrendVo> sell = mySellOrder.stream().map(item -> {
      // 根据订单中的商品ID获取商品信息
      ProductInfo productInfo = productInfoService.getById(item.getProductId());
      ProductInfoTrendVo bean = BeanUtil.toBean(productInfo, ProductInfoTrendVo.class);
      bean.setType("sell");
      // 使用订单创建时间作为时间戳
      bean.setCreateTime(item.getCreateTime().getTime());
      return bean;
    }).collect(Collectors.toList());

    // 将购买和销售的商品列表添加到发布列表中
    publish.addAll(buy);
    publish.addAll(sell);
    // 按创建时间降序排序，最新的记录排在前面
    publish.sort((o1, o2) -> (int) (o2.getCreateTime()-o1.getCreateTime()));
    // 返回成功结果和排序后的列表
    return R.ok(publish);
  }
  
  /**
   * 增加商品点赞数
   * @param productId 商品ID
   * @return 操作结果
   */
  @PutMapping("/like/count/{productId}")
  public R createLikeCount(@PathVariable("productId")String productId ){
    productInfoService.createLikeCount(productId);
    return R.ok();
  }

  //获取商品文档
  @SaIgnore
  @PostMapping("/doc")
  public String getDocById(@RequestParam("productId") String productId){
    return productInfoService.getDocById(productId);
  }
}

